package com.fcscs.ecms.dao.hibernate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.fcscs.core.dao.ConnectionManager;
import com.fcscs.core.domain.BaseEntity.DBLoc;
import com.fcscs.cservice.domain.PropertyConfiguration;
import com.fcscs.ecms.dao.ECMSCommonDao;
import com.fcscs.ecms.domain.GlobalHotelEntity;
import com.fcscs.ecms.domain.GlobalHotelRoomTypeList;
import com.fcscs.ecms.domain.GlobalHotelRoomTypeListId;
import com.fcscs.ecms.domain.GlobalLanguage;
import com.fcscs.ecms.domain.GlobalModuleInfo;
import com.fcscs.ecms.domain.GlobalModuleType;
import com.fcscs.ecms.domain.GlobalModuleType.ModuleType;
import com.fcscs.ecms.domain.GlobalPicture;
import com.fcscs.ecms.domain.GlobalProprietaryInfo;
import com.fcscs.ecms.domain.GlobalRoomType;
import com.fcscs.ecms.domain.GlobalText;
import com.fcscs.ecms.domain.GlobalTextId;
import com.fcscs.ecms.domain.HotelEntityView;
import com.fcscs.ecms.domain.MdlEntertainmentDynamicField;
import com.fcscs.ecms.domain.MdlEntertainmentElmts;
import com.fcscs.ecms.domain.MdlEntertainmentMain;
import com.fcscs.ecms.domain.MdlHelpCategory;
import com.fcscs.ecms.domain.MdlHelpMain;
import com.fcscs.ecms.domain.MdlHelpMainId;
import com.fcscs.ecms.domain.ScheduleActivation;
import com.fcscs.ecms.domain.ScheduleActivationId;

@SuppressWarnings("unchecked")
@Repository("ecmsCommonDao")
public class ECMSCommonDaoHibernate implements ECMSCommonDao {

	private static DBLoc CONFDBLoc = new PropertyConfiguration().getDBLoc();

	@Autowired
	private ConnectionManager connMgr;

	@Override
	public GlobalLanguage saveGlobalLanguage(GlobalLanguage entity) {
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(entity);
		return entity;
	}

	@Override
	public GlobalText saveGlobalText(GlobalText entity) {
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(entity);
		return entity;
	}

	@Override
	public GlobalPicture saveGlobalPicture(GlobalPicture entity) {
		int id = (Integer)connMgr.getCurrentSession(CONFDBLoc).save(entity);
		entity.setId(id);
		return entity;
	}

	@Override
	public GlobalPicture updateGlobalPicture(GlobalPicture entity) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).update(entity);
		return entity;
	}
	
	@Override
	public GlobalPicture getGlobalPicture(int id) {
		Object picObj = connMgr.getCurrentSession(CONFDBLoc).get(GlobalPicture.class, id);
		return picObj == null ? null : (GlobalPicture)picObj;
	}

	@Override
	public GlobalHotelEntity saveGlobalHotelEntity(GlobalHotelEntity entity) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(entity);
		return entity;
	}

	@Override
	public GlobalHotelRoomTypeList saveGlobalHotelRoomTypeList(
			GlobalHotelRoomTypeList entity) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).saveOrUpdate(entity);
		return entity;
	}

	@Override
	public List<GlobalText> getListGlobalText() {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				"from GlobalText");
		return q.list();
	}

	// Hotel Entity
	@Override
	public List<GlobalRoomType> getRoomType() {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				" from GlobalRoomType");
		return q.list();
	}

	@Override
	public List<String> getText(int id, String langId) {
		// TODO Auto-generated method stub
		Query q = connMgr
				.getCurrentSession(CONFDBLoc)
				.createSQLQuery(
						"select textUnicodeValue from ecms_hotel_staff_v02.global_text t where t.id = :Id and t.languageId = :langId ");
		q.setInteger("Id", id);
		q.setString("langId", langId);

		return q.list();

	}

	@Override
	public List<Integer> getHotelRoomTypeList(int idHotel) {
		// TODO Auto-generated method stub
		Query q = connMgr
				.getCurrentSession(CONFDBLoc)
				.createSQLQuery(
						"select roomTypeId from ecms_hotel_staff_v02.global_hotel_room_type_list t where t.hotelId = :Id");
		q.setInteger("Id", idHotel);

		return q.list();
	}

	@Override
	public List<GlobalPicture> getImage(int id) {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				" from GlobalPicture t where t.id = :Id");
		q.setInteger("Id", id);

		return q.list();
	}

	@Override
	public List<GlobalHotelEntity> getHotel(int id) {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				" from GlobalHotelEntity t where t.id = :Id");
		q.setInteger("Id", id);
		return q.list();
	}

	@Override
	public List<GlobalHotelEntity> getHotels() {
		// TODO Auto-generated method stub
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				" from GlobalHotelEntity");
		return q.list();
	}

	@Override
	public HotelEntityView getHotelEntityView(int id) {
		// TODO Auto-generated method stub
		HotelEntityView entity = (HotelEntityView) connMgr.getCurrentSession(
				CONFDBLoc).get(HotelEntityView.class, id);
		return entity;
	}

	@Override
	public Map<String, String> getGlobalTextMap(int textId) {
		String hql = "from GlobalText txt where txt.id.id = :textId";
		Query query = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		query.setInteger("textId", textId);
		List<GlobalText> list = (List<GlobalText>) query.list();
		Map<String, String> result = new HashMap<String, String>();
		for (GlobalText text : list) {
			result.put(text.getId().getLanguageId(), text.getTextUnicodeValue());
		}
		return result;
	}

	@Override
	public MdlEntertainmentDynamicField getEntertainmentDynamicField(int id) {
		return (MdlEntertainmentDynamicField) connMgr.getCurrentSession(
				CONFDBLoc).get(MdlEntertainmentDynamicField.class, id);
	}

	@Override
	public List<MdlEntertainmentDynamicField> getEntertainmentDynamicFieldList() {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				"from MdlEntertainmentDynamicField");
		return q.list();
	}

	@Override
	public MdlEntertainmentMain getEntertainmentMain(int id) {
		return (MdlEntertainmentMain) connMgr.getCurrentSession(CONFDBLoc).get(
				MdlEntertainmentMain.class, id);
	}

	@Override
	public List<MdlEntertainmentElmts> getEntertainmentElmtsList(int entMainId) {
		String hql = "from MdlEntertainmentElmts ele where ele.moduleId = :entMainId";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setInteger("entMainId", entMainId);
		return q.list();
	}

	@Override
	public Map<String, String> getLanguageMap() {
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				"from GlobalLanguage");
		List<GlobalLanguage> languageList = q.list();
		Map<String, String> languageMap = new HashMap<String, String>();
		for (GlobalLanguage lang : languageList) {
			languageMap.put(lang.getId(), lang.getDescription());
		}
		return languageMap;
	}

	@Override
	public int saveGlobalTextMap(Map<String, String> languageTextMap) {
		String hql = "select max(txt.id.id) from GlobalText txt";
		Session session = connMgr.getCurrentSession(CONFDBLoc);
		Query q = session.createQuery(hql);
		int nextId = (Integer) q.uniqueResult() + 1;
		GlobalText globalText;
		for (Entry<String, String> entry : languageTextMap.entrySet()) {
			globalText = new GlobalText(
					new GlobalTextId(nextId, entry.getKey()), entry.getValue());
			session.save(globalText);
		}
		return nextId;
	}

	@Override
	public void updateGlobalTextMap(int id, Map<String, String> languageTextMap) {
		String hql = "delete GlobalText txt where txt.id.id = :id";
		Session session = connMgr.getCurrentSession(CONFDBLoc);
		Query q = session.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
		GlobalText globalText;
		for (Entry<String, String> entry : languageTextMap.entrySet()) {
			globalText = new GlobalText(new GlobalTextId(id, entry.getKey()),
					entry.getValue());
			session.save(globalText);
		}
	}

	@Override
	public int saveGlobalModuleInfo(GlobalModuleInfo moduleInfo) {
		return (Integer) connMgr.getCurrentSession(CONFDBLoc).save(moduleInfo);
	}

	@Override
	public void updateGlobalModuleInfo(GlobalModuleInfo moduleInfo) {
		connMgr.getCurrentSession(CONFDBLoc).update(moduleInfo);
	}

	@Override
	public int saveEntertainmentMain(MdlEntertainmentMain entMain) {
		Session session = connMgr.getCurrentSession(CONFDBLoc);
		List<MdlEntertainmentElmts> entElmtsList = entMain
				.getEntertainmentElmts();
		int entMainId = (Integer) connMgr.getCurrentSession(CONFDBLoc).save(
				entMain);
		for (MdlEntertainmentElmts entElmts : entElmtsList) {
			entElmts.setProprietaryId(entMain.getProprietaryId());
			entElmts.setModuleId(entMainId);
			session.save(entElmts);
		}
		return entMainId;
	}

	@Override
	public void updateEntertainmentMain(MdlEntertainmentMain entMain) {
		Session session = connMgr.getCurrentSession(CONFDBLoc);
		List<MdlEntertainmentElmts> entElmtsList = entMain
				.getEntertainmentElmts();
		session.update(entMain);
		String hql = "delete MdlEntertainmentElmts ele where ele.moduleId = :moduleId";
		Query q = session.createQuery(hql);
		q.setInteger("moduleId", entMain.getId());
		q.executeUpdate();
		MdlEntertainmentElmts entElmtsItem;
		for (MdlEntertainmentElmts entElmts : entElmtsList) {
			entElmtsItem = new MdlEntertainmentElmts();
			entElmtsItem.setProprietaryId(entMain.getProprietaryId());
			entElmtsItem.setModuleId(entMain.getId());
			entElmtsItem.setFieldId(entElmts.getFieldId());
			entElmtsItem.setFieldName(entElmts.getFieldName());
			entElmtsItem.setIsActive(entElmts.isIsActive());
			session.save(entElmtsItem);
		}
	}

	@Override
	public int saveGlobalProprietaryInfo(GlobalProprietaryInfo propInfo) {
		return (Integer) connMgr.getCurrentSession(CONFDBLoc).save(propInfo);
	}

	@Override
	public void updateGlobalProprietaryInfo(GlobalProprietaryInfo propInfo) {
		connMgr.getCurrentSession(CONFDBLoc).update(propInfo);
	}

	@Override
	public GlobalProprietaryInfo getGlobalProprietaryInfo(int id) {
		return (GlobalProprietaryInfo) connMgr.getCurrentSession(CONFDBLoc)
				.get(GlobalProprietaryInfo.class, id);
	}

	@Override
	public GlobalModuleInfo getGlobalModuleInfo(int id) {
		return (GlobalModuleInfo) connMgr.getCurrentSession(CONFDBLoc).get(
				GlobalModuleInfo.class, id);
	}

	@Override
	public MdlEntertainmentMain getEntertainmentMain(int orgId, int propId,
			boolean isSchedule) {
		String hql = "select main from MdlEntertainmentMain main, " +
				"GlobalModuleInfo module, " +
				"GlobalProprietaryInfo propInfo " +
				"where module.typeId = :entType and propInfo.orgId = :orgId and propInfo.propId = :propId and module.isScheduleScreen = :isSchedule " +
				"and module.isTemplate = false and main.id = module.id and main.proprietaryId = propInfo.id";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setString("entType", GlobalModuleType.ModuleType.ENTERTAINMENT.getId());
		q.setInteger("orgId", orgId);
		q.setInteger("propId", propId);
		q.setBoolean("isSchedule", isSchedule);
		Object entMainObj = q.uniqueResult();
		return entMainObj == null ? null : (MdlEntertainmentMain)entMainObj;
	}

	@Override
	public void saveScheduleActivation(ScheduleActivation sche) {
		connMgr.getCurrentSession(CONFDBLoc).save(sche);
	}

	@Override
	public ScheduleActivation getScheduleActivation(ScheduleActivationId scheId) {
		return (ScheduleActivation) connMgr.getCurrentSession(CONFDBLoc).get(
				ScheduleActivation.class, scheId);
	}

	@Override
	public void updateScheduleActivation(ScheduleActivation sche) {
		connMgr.getCurrentSession(CONFDBLoc).update(sche);
	}

	@Override
	public ScheduleActivation getScheduleActivation(int orgId, int propId,
			String typeId) {
		String hql = "select sche from ScheduleActivation sche, "
				+ "GlobalProprietaryInfo propInfo "
				+ "where sche.proprietaryId = propInfo.id and sche.id.typeId = :typeId and propInfo.orgId = :orgId and propInfo.propId = :propId";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setString("typeId", typeId);
		q.setInteger("orgId", orgId);
		q.setInteger("propId", propId);
		Object scheObj = q.uniqueResult();
		return scheObj == null ? null : (ScheduleActivation) scheObj;
	}

	@Override
	public boolean deleteGlobalPicture(GlobalPicture pictureentity) {
		// TODO Auto-generated method stub
		connMgr.getCurrentSession(CONFDBLoc).delete(pictureentity);
		return true;
	}

	@Override
	public boolean deleteGlobalText(int id) {
		// TODO Auto-generated method stub
		String hql = "from GlobalText txt where txt.id.id = :textId";
		Query query = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		query.setInteger("textId", id);
		List<GlobalText> list = (List<GlobalText>) query.list();

		hql = "Delete GlobalText text where text.id=:Id";
		for (GlobalText text : list) {
			Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
			q.setProperties(text);
			q.executeUpdate();
		}

		return true;
	}

	@Override
	public boolean deleteHotelRoomTypeList(int idHotel, int roomTypeList) {
		// TODO Auto-generated method stub

		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(
				"Delete  GlobalHotelRoomTypeList t where t.id = :Id");

		GlobalHotelRoomTypeListId id = new GlobalHotelRoomTypeListId(idHotel,
				roomTypeList);
		GlobalHotelRoomTypeList roomtype = new GlobalHotelRoomTypeList(id);
		q.setProperties(roomtype);
		q.executeUpdate();

		return true;
	}

	@Override
	public boolean deleteHotel(int idHotel) {
		// TODO Auto-generated method stub

		String hql = "Delete GlobalHotelEntity t where t.id = :Id";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setInteger("Id", idHotel);
		q.executeUpdate();

		return true;
	}
	
	@Override
	public GlobalModuleInfo getGlobalModuleInfoTemplateByName(int orgId,
			int propId, ModuleType type, String templateName) {
		String hql = "select info from GlobalModuleInfo info, " +
				"GlobalProprietaryInfo propInfo " +
				"where info.proprietaryId = propInfo.id and info.typeId = :typeId and info.isTemplate = 1 and info.templateName = :templateName " +
				"and propInfo.orgId = :orgId and propInfo.propId = :propId";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setInteger("orgId", orgId);
		q.setInteger("propId", propId);
		q.setString("typeId", type.getId());
		q.setString("templateName", templateName);
		Object infoObj = q.uniqueResult();
		return infoObj == null ? null : (GlobalModuleInfo)infoObj;
	}
	
	@Override
	public List<GlobalModuleInfo> getGlobalModuleInfoTemplateList(int orgId,
			int propId, ModuleType type) {
		String hql = "select info from GlobalModuleInfo info, " +
				"GlobalProprietaryInfo propInfo " +
				"where info.proprietaryId = propInfo.id and info.typeId = :typeId and info.isTemplate = true " +
				"and propInfo.orgId = :orgId and propInfo.propId = :propId";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setInteger("orgId", orgId);
		q.setInteger("propId", propId);
		q.setString("typeId", type.getId());
		return q.list();
	}

	@Override
	public GlobalModuleInfo getHelpModuleInfo(int orgId, int propId,
			boolean isSchedule) {
		String hql = "select info from GlobalModuleInfo info, " +
				"GlobalProprietaryInfo propInfo " +
				"where info.proprietaryId = propInfo.id and info.typeId = :typeId and info.isTemplate = false and info.isScheduleScreen = :isSchedule " +
				"and propInfo.orgId = :orgId and propInfo.propId = :propId";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setInteger("orgId", orgId);
		q.setInteger("propId", propId);
		q.setString("typeId", ModuleType.HELP.getId());
		q.setBoolean("isSchedule", isSchedule);
		Object infoObj = q.uniqueResult();
		return infoObj == null ? null : (GlobalModuleInfo)infoObj;
	}

	@Override
	public List<MdlHelpMain> getHelpMainList(int moduleId) {
		String hql = "from MdlHelpMain main where main.id.id = :moduleId";
		Query q = connMgr.getCurrentSession(CONFDBLoc).createQuery(hql);
		q.setInteger("moduleId", moduleId);
		return q.list();
	}

	@Override
	public MdlHelpCategory getHelpCategory(int id) {
		Object helpCatObj = connMgr.getCurrentSession(CONFDBLoc).get(MdlHelpCategory.class, id);
		return helpCatObj == null ? null : (MdlHelpCategory)helpCatObj;
	}
	
	@Override
	public void deleteGlobalProprietaryInfo(int id) {
		Object obj = connMgr.getCurrentSession(CONFDBLoc).get(GlobalProprietaryInfo.class, id);
		if(obj != null){
			connMgr.getCurrentSession(CONFDBLoc).delete(obj);
		}
	}

	@Override
	public MdlHelpMainId saveHelpMain(MdlHelpMain helpMain) {
		return (MdlHelpMainId)connMgr.getCurrentSession(CONFDBLoc).save(helpMain);
	}

	@Override
	public int saveHelpCategory(MdlHelpCategory helpCat) {
		return (Integer)connMgr.getCurrentSession(CONFDBLoc).save(helpCat);
	}

	@Override
	public void deleteHelpMain(MdlHelpMain helpMain) {
		connMgr.getCurrentSession(CONFDBLoc).delete(helpMain);
	}

	@Override
	public void deleteHelpCategory(MdlHelpCategory helpCat) {
		connMgr.getCurrentSession(CONFDBLoc).delete(helpCat);
	}
	
	@Override
	public void updateHelpMain(MdlHelpMain helpMain) {
		connMgr.getCurrentSession(CONFDBLoc).update(helpMain);
	}
	
	@Override
	public void updateHelpCategory(MdlHelpCategory helpCat) {
		connMgr.getCurrentSession(CONFDBLoc).update(helpCat);
	}

}
